/*
 * CRUD-Flexigrid
 *
 * Copyright (c) 2009 Evgeny Gavrilenko
 * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2009-07-18 $
 */

(function($) {
	var datePattern=/^\/Date\((\d+)(?:[+-](\d+))?\)\/$/;
	Date.prototype.toJSON=function(key){
		return '/Date('+this.valueOf()+')/';
	};
	$.extend({
		inherit:function(Child, Parent) {
			var F = function() { };
			F.prototype = Parent.prototype;
			Child.prototype = new F();
			Child.prototype.constructor = Child;
			Child.superclass = Parent.prototype;
			
			//$.extend(true, Child, Parent);
		},
		dateNet: function(date){
			if(date===null||date===undefined) return null;
			var d=datePattern.exec(date);
			return new Date(parseInt(d[1]));
		}
	});
	$.fn.gridFormatters={};
	$.fn.gridFormatters.textFormatter=function(){};
	$.fn.gridFormatters.textFormatter.prototype={
		stringify:function(data){
			return (data>'')?data:'&nbsp;';
		},
		edit:function(data){
			var obj=$('<input type="text"/>');
			obj[0].value=data;
			return obj;
		},
		parseInput:function(obj){return obj.value;},
		preProcess:function(value){return value;}
	};
	var ff={	
		dateFormatter:function(format,settings){
			this.format=format?format:'yy-mm-dd hh:ii';
			this.settings=settings;
			
			this.stringify=function(date){
				function f(n) {return n < 10 ? '0' + n : n;}
				//(new Date()).getDate
				return f(date.getUTCMonth()+1)+'/'+f(date.getUTCDate()+1)+'/'+f(date.getUTCFullYear());
				//return $.datetimepicker.formatDate(this.format, date, this.settings);
			};
			this.parseInput=function(obj){
				//$.datetimepicker.parseDate(this.format, obj.value, this.settings);
				var date= Date.parse(obj.value);
				return new Date(date);
			};
			this.edit=function(date){
				var obj=$('<input type="text"/>');
				obj[0].value=this.stringify(date);
				return obj;
			};
			this.preProcess=function(value){return $.dateNet(value);}
		},		
		checkboxFormatter:function(){
			this.stringify=function(data){
				return '<input type="checkbox" disabled '+(data?'checked':'')+'/>';
			};
			this.parse=function(value){
				var v=value.toLowerCase();
				return v==='on'||v=='1'||v==='true';
			};
			this.parseInput=function(obj){
				if (obj.type==='checkbox'){
					return obj.checked;
				}else{
					return this.parse(obj.value);
				}
			};
			this.edit=function(data){
				return obj=$('<input type="checkbox" '+(data?'checked':'')+'"/>');
			};
		},
		selectFormatter:function(options){
			this.options=options;
			this.stringData=function(data){
				if(data || (typeof(data)==='boolean'))
					data=data.toString();
				return (data>'')?data:'&nbsp;';
			};
			this.stringify=function(data){
				data=this.stringData(data);
				var s;
				$.each(this.options,function(i,o){
					var v,t;
					if(typeof(o)==='object'){
						v=o.value.toString();
						t=o.text;
					}else{
						v=t=o;
					}
					if(data==v)s=t;
				});
				return s;
			}
			this.edit=function(data){
				data=this.stringData(data);
				var s='<select>';
				$.each(this.options,function(i,o){
					var v,t;
					if(typeof(o)==='object'){
						v=o.value;
						t=o.text;
					}else{
						v=t=o;
					}
					s+='<option value="'+v+'" '+(data==o?'selected ':'')+'>'+t+'</option>';
				});
				s+='</select>';
				return $(s);
			},
			this.parseInput=function(obj){
				return obj.options[obj.selectedIndex].value;
			};
		},
		linkFormatter:function(){
			this.stringify=function(data){
				return '<a href="'+data+'" >'+data+'</a>';
			}
		},
		mailFormatter:function(){
			this.stringify=function(data){
				return '<a href="mailto:'+data+'" >'+data+'</a>';
			}
		}
	};
			
	$.each(ff,function(i,F){
		$.inherit(F,$.fn.gridFormatters.textFormatter);
	});
	$.extend($.fn.gridFormatters,ff);
	
	$.addFlex=function(t,p) {

		if(t.grid) return false; //return if already exist	

		// apply default properties
		p=$.extend({
			ds:{'total':0,'page':1,'rows':[]},//dataSource
			height: 200, //default height
			width: 'auto', //auto width
			striped: true, //apply odd even stripes
			novstripe: false,
			minwidth: 30, //min width of columns
			minheight: 80, //min height of columns
			resizable: true, //resizable table
			url: false, //ajax url
			method: 'POST', // data sending method
			dataType: 'json', // type of data loaded
			errormsg: 'Connection Error',
			usepager: false, //
			nowrap: true, //
			page: 1, //current page
			total: 1, //total pages
			useRp: true, //use the results per page select box
			rp: 15, // results per page
			rpOptions: [10,15,20,25,40],
			title: false,
			pagestat: 'Displaying {from} to {to} of {total} items',
			procmsg: 'Processing, please wait ...',
			query: '',
			qtype: '',
			nomsg: 'No items',
			minColToggle: 1, //minimum allowed column to be hidden
			showToggleBtn: true, //show or hide column toggle popup
			hideOnSubmit: true,
			autoload: true,
			blockOpacity: 0.5,
			onToggleCol: false,
			onChangeSort: false,
			onSuccess: false,
			onSubmit: false // using a custom populate function
		},p);
				
		p.CRUD={
			create: function(obj,success,error){
				$.ajax({
					type: "POST",
					url: p.url,
					data: JSON.stringify(obj),
					contentType: "application/json",
					dataType: p.dataType,
					success: success,
					error: error
				});
			},
			read: function(id,success,error) {
				$.ajax({
					type: "GET",
					url: p.url+id,
					dataType: p.dataType,
					success: success,
					error: error
				});
			},
			update: function(id,obj,success,error) {
				$.ajax({
					type: "PUT",
					url: p.url+id,
					data: JSON.stringify(obj),
					dataType: p.dataType,
					contentType: "application/json",
					success: success,
					error: error
				});
			},
			delete: function(id,success,error){
				$.ajax({
		 			type: "DELETE",
		 			url: p.url+id,
		 			success: success,
		 			error: error
		 		});
			},
			bulkDelete:function(arr_id,success,error){
				$.ajax({
					type: "DELETE",
					url: p.url+"BulkDelete",
					data: JSON.stringify(arr_id),
					contentType: "application/json",
					success: success,
					error: error
				});
			},
//			bulkUpdate:function(arr_obj,success,error){
//				$.ajax({
//					type: "PUT",
//					url: p.url+"BulkUpdate",
//					data: JSON.stringify(arr_obj),
//					contentType: "application/json",
//					success: success,
//					error: error
//				});
//			},
			get: function(page,rows, sort, dir, filter,success,error){
				var param=[
					 { name: 'page',value: page }
					,{ name: 'rp',value: rows }
					,{ name: 'sortname',value: sort }
					,{ name: 'sortorder',value: dir }
					,{ name: 'query',value: filter }
				];

				if(p.params) {
					for(var pi=0;pi<p.params.length;pi++) param[param.length]=p.params[pi];
				}

				$.ajax({
					type: "GET",
					url: p.url+"Get",
					data: param,
					dataType: p.dataType,
					success: success,
					error: error
				});
			}
		};
		
		p.formatters={
				formatData:function(row,idx) {
					var col=p.colModel[idx];
	 				var f=col._formatter;
	 				var data=row[col.name];
	 				return f.stringify(data);
	 			},
	 			getFormatter:function(f){
	 				var ftype;
	 				if(!f){
	 					ftype="text";
	 				}else if(typeof(f)==="string"){
	 					ftype=f;
	 				}else{
	 					ftype=f.name;
	 				}
	 				
	 				ftype=ftype.toLowerCase();
 					switch(ftype) {
 						case 'date':
 							return new $.fn.gridFormatters.dateFormatter(f.format, f.settings);
 						case 'checkbox':
 							return new $.fn.gridFormatters.checkboxFormatter();
 						case 'select':
 							return new $.fn.gridFormatters.selectFormatter(f.options);	
 						case 'link':
 							return new $.fn.gridFormatters.linkFormatter();
 						case 'email':
 							return new $.fn.gridFormatters.mailFormatter();
 						default:
 							return new $.fn.gridFormatters.textFormatter();
 					}
	 			},
	 			format:function(data,f){
	 				this.getFormatter(f).stringify(data);
	 			}
	 	};
	 	$.each(p.colModel, function(i,col){
	 		col._formatter=p.formatters.getFormatter(col.formatter);
	 	});
	 	p.preProcessRow=function(row){
			$.each(p.colModel,function(i,col){row[col.name]=col._formatter.preProcess(row[col.name]);});
		};

		$(t)
		.show() //show if hidden
		.attr({ cellPadding: 0,cellSpacing: 0,border: 0 })  //remove padding and spacing
		.removeAttr('width') //remove width properties	
		;
		
		
		//create grid class
		var g={
			hset: {},
			rePosDrag: function() {

				var cdleft=0-this.hDiv.scrollLeft;
				if(this.hDiv.scrollLeft>0) cdleft-=Math.floor(p.cgwidth/2);
				$(g.cDrag).css({ top: g.hDiv.offsetTop+1 });
				var cdpad=this.cdpad;

				$('div',g.cDrag).hide();

				$('thead tr:first th:visible',this.hDiv).each
				(
			 	function() {
			 		var n=$('thead tr:first th:visible',g.hDiv).index(this);

			 		var cdpos=parseInt($('div',this).width());
			 		var ppos=cdpos;
			 		if(cdleft==0)
			 			cdleft-=Math.floor(p.cgwidth/2);

			 		cdpos=cdpos+cdleft+cdpad;

			 		$('div:eq('+n+')',g.cDrag).css({ 'left': cdpos+'px' }).show();

			 		cdleft=cdpos;
			 	}
				);

			},
			fixHeight: function(newH) {
				newH=false;
				if(!newH) newH=$(g.bDiv).height();
				var hdHeight=$(this.hDiv).height();
				$('div',this.cDrag).each(
						function() {
							$(this).height(newH+hdHeight);
						}
					);

				var nd=parseInt($(g.nDiv).height());

				if(nd>newH)
					$(g.nDiv).height(newH).width(200);
				else
					$(g.nDiv).height('auto').width('auto');

				$(g.block).css({ height: newH,marginBottom: (newH* -1) });

				var hrH=g.bDiv.offsetTop+newH;
				if(p.height!='auto'&&p.resizable) hrH=g.vDiv.offsetTop;
				$(g.rDiv).css({ height: hrH });

			},
			dragStart: function(dragtype,e,obj) { //default drag function start

				if(dragtype=='colresize') //column resize
				{
					$(g.nDiv).hide();$(g.nBtn).hide();
					var n=$('div',this.cDrag).index(obj);
					var ow=$('th:visible div:eq('+n+')',this.hDiv).width();
					$(obj).addClass('dragging').siblings().hide();
					$(obj).prev().addClass('dragging').show();

					this.colresize={ startX: e.pageX,ol: parseInt(obj.style.left),ow: ow,n: n };
					$('body').css('cursor','col-resize');
				}
				else if(dragtype=='vresize') //table resize
				{
					var hgo=false;
					$('body').css('cursor','row-resize');
					if(obj) {
						hgo=true;
						$('body').css('cursor','col-resize');
					}
					this.vresize={ h: p.height,sy: e.pageY,w: p.width,sx: e.pageX,hgo: hgo };

				}

				else if(dragtype=='colMove') //column header drag
				{
					$(g.nDiv).hide();$(g.nBtn).hide();
					this.hset=$(this.hDiv).offset();
					this.hset.right=this.hset.left+$('table',this.hDiv).width();
					this.hset.bottom=this.hset.top+$('table',this.hDiv).height();
					this.dcol=obj;
					this.dcoln=$('th',this.hDiv).index(obj);

					this.colCopy=document.createElement("div");
					this.colCopy.className="colCopy";
					this.colCopy.innerHTML=obj.innerHTML;
					if($.browser.msie) {
						this.colCopy.className="colCopy ie";
					}


					$(this.colCopy).css({ position: 'absolute',float: 'left',display: 'none',textAlign: obj.align });
					$('body').append(this.colCopy);
					$(this.cDrag).hide();

				}

				$('body').noSelect();

			},
			dragMove: function(e) {

				if(this.colresize) //column resize
				{
					var n=this.colresize.n;
					var diff=e.pageX-this.colresize.startX;
					var nleft=this.colresize.ol+diff;
					var nw=this.colresize.ow+diff;
					if(nw>p.minwidth) {
						$('div:eq('+n+')',this.cDrag).css('left',nleft);
						this.colresize.nw=nw;
					}
				}
				else if(this.vresize) //table resize
				{
					var v=this.vresize;
					var y=e.pageY;
					var diff=y-v.sy;

					if(!p.defwidth) p.defwidth=p.width;

					if(p.width!='auto'&&!p.nohresize&&v.hgo) {
						var x=e.pageX;
						var xdiff=x-v.sx;
						var newW=v.w+xdiff;
						if(newW>p.defwidth) {
							this.gDiv.style.width=newW+'px';
							p.width=newW;
						}
					}

					var newH=v.h+diff;
					if((newH>p.minheight||p.height<p.minheight)&&!v.hgo) {
						this.bDiv.style.height=newH+'px';
						p.height=newH;
						this.fixHeight(newH);
					}
					v=null;
				}
				else if(this.colCopy) {
					$(this.dcol).addClass('thMove').removeClass('thOver');
					if(e.pageX>this.hset.right||e.pageX<this.hset.left||e.pageY>this.hset.bottom||e.pageY<this.hset.top) {
						//this.dragEnd();
						$('body').css('cursor','move');
					}
					else
						$('body').css('cursor','pointer');
					$(this.colCopy).css({ top: e.pageY+10,left: e.pageX+20,display: 'block' });
				}

			},
			dragEnd: function() {

				if(this.colresize) {
					var n=this.colresize.n;
					var nw=this.colresize.nw;

					$('th:visible div:eq('+n+')',this.hDiv).css('width',nw);
					$('tr',this.bDiv).each(
									function() {
										$('td:visible div:eq('+n+')',this).css('width',nw);
									}
								);
					this.hDiv.scrollLeft=this.bDiv.scrollLeft;


					$('div:eq('+n+')',this.cDrag).siblings().show();
					$('.dragging',this.cDrag).removeClass('dragging');
					this.rePosDrag();
					this.fixHeight();
					this.colresize=false;
				}
				else if(this.vresize) {
					this.vresize=false;
				}
				else if(this.colCopy) {
					$(this.colCopy).remove();
					if(this.dcolt!=null) {


						if(this.dcoln>this.dcolt)

							$('th:eq('+this.dcolt+')',this.hDiv).before(this.dcol);
						else
							$('th:eq('+this.dcolt+')',this.hDiv).after(this.dcol);



						this.switchCol(this.dcoln,this.dcolt);
						$(this.cdropleft).remove();
						$(this.cdropright).remove();
						this.rePosDrag();


					}

					this.dcol=null;
					this.hset=null;
					this.dcoln=null;
					this.dcolt=null;
					this.colCopy=null;

					$('.thMove',this.hDiv).removeClass('thMove');
					$(this.cDrag).show();
				}
				$('body').css('cursor','default');
				$('body').noSelect(false);
			},
			toggleCol: function(cid,visible) {

				var ncol=$("th[axis='col"+cid+"']",this.hDiv)[0];
				var n=$('thead th',g.hDiv).index(ncol);
				var cb=$('input[value='+cid+']',g.nDiv)[0];


				if(visible==null) {
					visible=ncol.hide;
				}



				if($('input:checked',g.nDiv).length<p.minColToggle&&!visible) return false;

				if(visible) {
					ncol.hide=false;
					$(ncol).show();
					cb.checked=true;
				}
				else {
					ncol.hide=true;
					$(ncol).hide();
					cb.checked=false;
				}

				$('tbody tr',t).each
							(
								function() {
									if(visible)
										$('td:eq('+n+')',this).show();
									else
										$('td:eq('+n+')',this).hide();
								}
							);

				this.rePosDrag();

				if(p.onToggleCol) p.onToggleCol(cid,visible);

				return visible;
			},
			switchCol: function(cdrag,cdrop) { //switch columns

				$('tbody tr',t).each
					(
						function() {
							if(cdrag>cdrop)
								$('td:eq('+cdrop+')',this).before($('td:eq('+cdrag+')',this));
							else
								$('td:eq('+cdrop+')',this).after($('td:eq('+cdrag+')',this));
						}
					);

				//switch order in nDiv
				if(cdrag>cdrop)
					$('tr:eq('+cdrop+')',this.nDiv).before($('tr:eq('+cdrag+')',this.nDiv));
				else
					$('tr:eq('+cdrop+')',this.nDiv).after($('tr:eq('+cdrag+')',this.nDiv));

				if($.browser.msie&&$.browser.version<7.0) $('tr:eq('+cdrop+') input',this.nDiv)[0].checked=true;

				this.hDiv.scrollLeft=this.bDiv.scrollLeft;
			},
			scroll: function() {
				this.hDiv.scrollLeft=this.bDiv.scrollLeft;
				this.rePosDrag();
			},
			
			addData: function(data) { //parse data

				if(data){
					$.each(data.rows,function(i,row) {p.preProcessRow(row);});	
				
					if(p.preProcess)
						data=p.preProcess(data);	
					g.ds=data;
				}
				
				$('.pReload',this.pDiv).removeClass('loading');
				this.loading=false;

				if(!g.ds) {
					$('.pPageStat',this.pDiv).html(p.errormsg);
					return false;
				}

				p.total=g.ds.total;
				if(p.total==0) {
					$('tr, a, td, div',t).unbind();
					$(t).empty();
					p.pages=1;
					p.page=1;
					this.buildpager();
					$('.pPageStat',this.pDiv).html(p.nomsg);
					return false;
				}

				p.pages=Math.ceil(p.total/p.rp);
				p.page=g.ds.page;

				this.buildpager();

				//build new body
				var tbody=document.createElement('tbody');

				$.each(g.ds.rows,function(i,row) {
					
				 	var tr=document.createElement('tr');
				 	
				 	//if(row.id) tr.id='row'+row.id;
				 	tr.id='row'+row[g.ds.key];
				 	
				 	tr.rowData=row;
				 	//add cell
				 	$('thead tr:first th',g.hDiv).each(function() {
				 		var td=document.createElement('td');
				 		var idx=$(this).attr('axis').substr(3);
				 		td.align=this.align;
				 		td.innerHTML=p.formatters.formatData(row,idx);
				 		$(tr).append(td);
				 		td=null;
				 	});


				 	if($('thead',this.gDiv).length<1){ //handle if grid has no headers
				 		for(idx=0;idx<cell.length;idx++) {
				 			var td=document.createElement('td');
				 			td.innerHTML=p.formatters.formatData(row,idx);
				 			$(tr).append(td);
				 			td=null;
				 		}
				 	}

				 	$(tbody).append(tr);
				 	if(tr.rowIndex%2&&p.striped) tr.className='erow';

				 	tr=null;
				});

				

				$('tr',t).unbind();
				$(t).empty();

				$(t).append(tbody);
				this.addCellProp();
				this.addRowProp();

				//this.fixHeight($(this.bDiv).height());

				this.rePosDrag();

				tbody=null;data=null;i=null;

				if(p.onSuccess) p.onSuccess();
				if(p.hideOnSubmit) $(g.block).remove(); //$(t).show();

				this.hDiv.scrollLeft=this.bDiv.scrollLeft;
				if($.browser.opera) $(t).css('visibility','visible');

			},
			changeSort: function(th) { //change sortorder

				if(this.loading) return true;

				$(g.nDiv).hide();$(g.nBtn).hide();

				if(p.sortname==$(th).attr('abbr')) {
					if(p.sortorder=='asc') p.sortorder='desc';
					else p.sortorder='asc';
				}

				$(th).addClass('sorted').siblings().removeClass('sorted');
				$('.sdesc',this.hDiv).removeClass('sdesc');
				$('.sasc',this.hDiv).removeClass('sasc');
				$('div',th).addClass('s'+p.sortorder);
				p.sortname=$(th).attr('abbr');

				if(p.onChangeSort)
					p.onChangeSort(p.sortname,p.sortorder);
				else
					this.populate();

			},
			buildpager: function() { //rebuild pager based on new properties

				$('.pcontrol input',this.pDiv).val(p.page);
				$('.pcontrol span',this.pDiv).html(p.pages);

				var r1=(p.page-1)*p.rp+1;
				var r2=r1+p.rp-1;

				if(p.total<r2) r2=p.total;

				var stat=p.pagestat;

				stat=stat.replace(/{from}/,r1);
				stat=stat.replace(/{to}/,r2);
				stat=stat.replace(/{total}/,p.total);

				$('.pPageStat',this.pDiv).html(stat);

			},
			populate: function() { //get latest data

				if(this.loading) return true;

				if(p.onSubmit) {
					var gh=p.onSubmit();
					if(!gh) return false;
				}

				this.loading=true;
				if(!p.url) return false;

				$('.pPageStat',this.pDiv).html(p.procmsg);

				$('.pReload',this.pDiv).addClass('loading');

				$(g.block).css({ top: g.bDiv.offsetTop });

				if(p.hideOnSubmit) $(this.gDiv).prepend(g.block); //$(t).hide();

				if($.browser.opera) $(t).css('visibility','hidden');

				if(!p.newp) p.newp=1;

				if(p.page>p.pages) p.page=p.pages;
				
				if (p.CRUD){
					p.CRUD.get(p.newp, p.rp, p.sortname, p.sortorder, p.query,
						function(data) { g.addData(data); },
						function(data) { try { if(p.onError) p.onError(data); } catch(e) { } }
					);
				}
			},
			deleteSelected: function(){
				var sr=$('.trSelected',this.gDiv);
				if(sr.length<1) return;
				if(confirm('Delete '+sr.length+' items?')) {
					var id=[];
					sr.each(function() {id.push(this.rowData[g.ds.key]);});
					
					p.CRUD.bulkDelete(id,
						function(data){
							sr.each(function(){
								g.ds.rows.splice(this.rowIndex,1);
								this.rowData=null;
								this.parentNode.deleteRow(this.rowIndex);});
						},
						function(data) { try { if(p.onError) p.onError(data); } catch(e) { } });
					
				}
			},
			editSelected: function(){
				var sr=$('.trSelected',this.gDiv);
				if(sr.length<1) return;
				g.inlineEditor.edit(sr[0]);				
			},
			addRecord:function(){
				g.inlineEditor.edit();
			},
			doSearch: function() {
				p.query=$('input[name=q]',g.sDiv).val();
				p.qtype=$('select[name=qtype]',g.sDiv).val();
				p.newp=1;

				this.populate();
			},
			changePage: function(ctype) { //change page

				if(this.loading) return true;

				switch(ctype) {
					case 'first': p.newp=1;break;
					case 'prev': if(p.page>1) p.newp=parseInt(p.page)-1;break;
					case 'next': if(p.page<p.pages) p.newp=parseInt(p.page)+1;break;
					case 'last': p.newp=p.pages;break;
					case 'input':
						var nv=parseInt($('.pcontrol input',this.pDiv).val());
						if(isNaN(nv)) nv=1;
						if(nv<1) nv=1;
						else if(nv>p.pages) nv=p.pages;
						$('.pcontrol input',this.pDiv).val(nv);
						p.newp=nv;
						break;
				}

				if(p.newp==p.page) return false;

				if(p.onChangePage)
					p.onChangePage(p.newp);
				else
					this.populate();

			},
			addCellProp: function() {

				$('tbody tr td',g.bDiv).each
					(
						function() {
							var tdDiv=document.createElement('div');
							var n=$('td',$(this).parent()).index(this);
							var pth=$('th:eq('+n+')',g.hDiv).get(0);

							if(pth!=null) {
								if(p.sortname==$(pth).attr('abbr')&&p.sortname) {
									this.className='sorted';
								}
								$(tdDiv).css({ textAlign: pth.align,width: $('div:first',pth)[0].style.width });

								if(pth.hide) $(this).css('display','none');

							}

							if(p.nowrap==false) $(tdDiv).css('white-space','normal');

							if(this.innerHTML=='') this.innerHTML='&nbsp;';

							//tdDiv.value = this.innerHTML; //store preprocess value
							tdDiv.innerHTML=this.innerHTML;

							var prnt=$(this).parent()[0];
							var pid=false;
							if(prnt.id) pid=prnt.id.substr(3);

							if(pth!=null) {
								if(pth.process) pth.process(tdDiv,pid);
							}

							$(this).empty().append(tdDiv).removeAttr('width'); //wrap content

							//add editable event here 'dblclick'

						}
					);

			},
			getCellDim: function(obj) // get cell prop for editable event
			{
				var ht=parseInt($(obj).height());
				var pht=parseInt($(obj).parent().height());
				var wt=parseInt(obj.style.width);
				var pwt=parseInt($(obj).parent().width());
				var top=obj.offsetParent.offsetTop;
				var left=obj.offsetParent.offsetLeft;
				var pdl=parseInt($(obj).css('paddingLeft'));
				var pdt=parseInt($(obj).css('paddingTop'));
				return { ht: ht,wt: wt,top: top,left: left,pdl: pdl,pdt: pdt,pht: pht,pwt: pwt };
			},
			updateRow: function(row,data){
				if(!data)return;
				p.preProcessRow(data);
				row.rowData=data;
				$.each($("th", g.hDiv),function(i,th){
					var cname=$(th).attr('abbr');
					var col=$.grep(p.colModel, function(colm,i){return colm.name==cname;})[0];
					var target=$('td:eq('+this.cellIndex+')',row)[0];
					target.children[0].innerHTML=col._formatter.stringify(row.rowData[cname]);
				});
			},
			addRowProp: function() {
				$('tbody tr',g.bDiv).each
					(
						function() {
							$(this)
							.click(
								function(e) {
									var obj=(e.target||e.srcElement);if(obj.href||obj.type) return true;
									$(this).toggleClass('trSelected');
									if(p.singleSelect) $(this).siblings().removeClass('trSelected');
									if(p.rowClick) p.rowClick(this);
									
								}
							)
							.dblclick(
								function(e) {
									if(p.useInlineEditor){
										g.inlineEditor.edit(this);
									}
								}
							)
							.mousedown(
								function(e) {
									if(!p.singleSelect && e.shiftKey) {
										$(this).toggleClass('trSelected');
										g.multisel=true;
										this.focus();
										$(g.gDiv).noSelect();
									}
								}
							)
							.mouseup(
								function() {
									if(g.multisel) {
										g.multisel=false;
										$(g.gDiv).noSelect(false);
									}
								}
							)
							.hover(
								function(e) {
									if(g.multisel) {
										$(this).toggleClass('trSelected');
									}
								},
								function() { }
							)
							;

							if($.browser.msie&&$.browser.version<7.0) {
								$(this)
									.hover(
										function() { $(this).addClass('trOver'); },
										function() { $(this).removeClass('trOver'); }
									)
									;
							}
						}
					);


			},
			pager: 0
		};

		//create model if any
		if(p.colModel) {
			thead=document.createElement('thead');
			tr=document.createElement('tr');

			for(i=0;i<p.colModel.length;i++) {
				var cm=p.colModel[i];
				var th=document.createElement('th');

				th.innerHTML=cm.display;

				if(cm.name&&cm.sortable)
					$(th).attr('abbr',cm.name);

				//th.idx = i;
				$(th).attr('axis','col'+i);

				if(cm.align)
					th.align=cm.align;

				if(cm.width)
					$(th).attr('width',cm.width);

				if(cm.hide) {
					th.hide=true;
				}

				if(cm.process) {
					th.process=cm.process;
				}

				$(tr).append(th);
			}
			$(thead).append(tr);
			$(t).prepend(thead);
		} // end if p.colmodel	

		//init divs
		g.gDiv=document.createElement('div'); //create global container
		g.mDiv=document.createElement('div'); //create title container
		g.hDiv=document.createElement('div'); //create header container
		g.bDiv=document.createElement('div'); //create body container
		g.vDiv=document.createElement('div'); //create grip
		g.rDiv=document.createElement('div'); //create horizontal resizer
		g.cDrag=document.createElement('div'); //create column drag
		g.block=document.createElement('div'); //creat blocker
		g.nDiv=document.createElement('div'); //create column show/hide popup
		g.nBtn=document.createElement('div'); //create column show/hide button
		g.iDiv=document.createElement('div'); //create editable layer
		g.tDiv=document.createElement('div'); //create toolbar
		g.sDiv=document.createElement('div');

		if(p.usepager) g.pDiv=document.createElement('div'); //create pager container
		g.hTable=document.createElement('table');

		//set gDiv
		g.gDiv.className='flexigrid';
		if(p.width!='auto') g.gDiv.style.width=p.width+'px';

		//add conditional classes
		if($.browser.msie)
			$(g.gDiv).addClass('ie');

		if(p.novstripe)
			$(g.gDiv).addClass('novstripe');

		$(t).before(g.gDiv);
		$(g.gDiv)
		.append(t)
		;
		
		if(p.useInlineEditor){
			g.inlineEditor={
				init:function(){
					this.cDiv=document.createElement('div');
					this.cDiv.className="inlineEditor";
					$(this.cDiv).append('<div class="etDiv"></div>');
					$(this.cDiv).append('<div class="ebDiv"><div class="btnUpdate eButton"><span>Save</span></div><div class="btnCancel eButton"><span>Cancel</span></div></div>');
					$('.btnUpdate',this.cDiv).click(function(){g.inlineEditor.update()});
					$('.btnCancel',this.cDiv).click(function(){g.inlineEditor.cancel()});
					$(document.body).append(this.cDiv);
				},
				update:function(){
					var e=g.inlineEditor;
					var data=e.activeRow?e.activeRow.rowData:{};
					$.each($("th:visible", g.hDiv),function(i,th){
						var cname=$(th).attr('abbr');
						var col=$.grep(t.p.colModel, function(colm,i){return colm.name==cname;})[0];
						if(!col.editable)return;
						
						var source=$('td:eq('+i+')',e.cDiv)[0];
						var f=col._formatter;
						var value=f.parseInput(source.children[0]);
						data[cname]=value;
					});
					
					if(e.activeRow){
						t.p.CRUD.update(data[g.ds.key],data,
							function(obj){
								g.updateRow(e.activeRow,obj);
								e.activeRow=null;
								e.hide();
							},null);
					}else{
						t.p.CRUD.create(data,
							function(obj){
								var ds=g.ds;
								ds.total++;
								ds.rows.push(obj);
								g.ds=ds;
								g.addData()
								e.hide();
							},null);
					}
				},
				cancel:function(){
					this.hide();
				},
				edit:function(row){
					this.editMode=true;
					if(row)
						$(row).addClass('trSelected').siblings().removeClass('trSelected');//remove selections
					this.modalDiv=document.createElement('div');//hide table under div
					$(this.modalDiv).addClass('modalDiv');
					$(this.modalDiv).css({
						'height':$(g.gDiv).height(),
						'width':$(g.gDiv).width()
					});
					$(g.gDiv).append(this.modalDiv);
					
					this.activeRow=row;

					var etd=$(this.cDiv.firstChild);
					etd.empty().append('<table><tr><tr></table>');
					var tr=etd[0].children[0].rows[0];
					$("th:visible", g.hDiv).each(function(){
						var cname=$(this).attr('abbr');
						var data=row?row.rowData[cname]:null;
						var col=$.grep(t.p.colModel, function(colm,i){return colm.name==cname;})[0];
						var td=tr.insertCell(-1);
						var cw=$(this).width();
						if(col.editable){
							var obj=col._formatter.edit(data);
							obj.css({'width': cw-6, 'margin-left':2});
							$(td).append(obj);	
						}else{
							td.innerHTML=col._formatter.stringify(data);
							td.style.textAlign='center';
						}
						$(td).css({'width':cw,'border':'none'});
					});
					
					var wr=row?$(row):$(g.bDiv);
					var p=wr.offset();
					$(this.cDiv).css({
					'top':p.top,
					'left':p.left,
					'width':wr.width(),
					 'display':'block'});
				},
				hide:function(){
					$(this.cDiv).css({'display':'none'});
					$(this.modalDiv).remove();
					this.editMode=false;
				}
			};
			g.inlineEditor.init();
		}
		//set toolbar
		if(p.buttons) {
			g.tDiv.className='tDiv';
			var tDiv2=document.createElement('div');
			tDiv2.className='tDiv2';

			for(i=0;i<p.buttons.length;i++) {
				var btn=p.buttons[i];
				if(!btn.separator) {
					var btnDiv=document.createElement('div');
					btnDiv.className='fbutton';
					btnDiv.innerHTML="<div><span>"+btn.name+"</span></div>";
					if(btn.bclass)
						$('span',btnDiv)
							.addClass(btn.bclass)
							.css({ paddingLeft: 20 })
							;
					btnDiv.onpress=btn.onpress;
					btnDiv.name=btn.name;
					if(btn.onpress) {
						$(btnDiv).click
							(
								function() {
									this.onpress(this.name,g,p);
								}
							);
					}
					$(tDiv2).append(btnDiv);
					if($.browser.msie&&$.browser.version<7.0) {
						$(btnDiv).hover(function() { $(this).addClass('fbOver'); },function() { $(this).removeClass('fbOver'); });
					}

				} else {
					$(tDiv2).append("<div class='btnseparator'></div>");
				}
			}
			$(g.tDiv).append(tDiv2);
			$(g.tDiv).append("<div style='clear:both'></div>");
			$(g.gDiv).prepend(g.tDiv);
		}

		//set hDiv
		g.hDiv.className='hDiv';

		$(t).before(g.hDiv);

		//set hTable
		g.hTable.cellPadding=0;
		g.hTable.cellSpacing=0;
		$(g.hDiv).append('<div class="hDivBox"></div>');
		$('div',g.hDiv).append(g.hTable);
		var thead=$("thead:first",t).get(0);
		if(thead) $(g.hTable).append(thead);
		thead=null;

		if(!p.colmodel) var ci=0;

		//setup thead			
		$('thead tr:first th',g.hDiv).each
			(
			 	function() {
			 		var thdiv=document.createElement('div');



			 		if($(this).attr('abbr')) {
			 			$(this).click(
								function(e) {

									if(!$(this).hasClass('thOver')) return false;
									var obj=(e.target||e.srcElement);
									if(obj.href||obj.type) return true;
									g.changeSort(this);
								}
							)
							;

			 			if($(this).attr('abbr')==p.sortname) {
			 				this.className='sorted';
			 				thdiv.className='s'+p.sortorder;
			 			}
			 		}

			 		if(this.hide) $(this).hide();

			 		if(!p.colmodel) {
			 			$(this).attr('axis','col'+ci++);
			 		}


			 		$(thdiv).css({ textAlign: this.align,width: this.width+'px' });
			 		thdiv.innerHTML=this.innerHTML;

			 		$(this).empty().append(thdiv).removeAttr('width')
						.mousedown(function(e) {
							g.dragStart('colMove',e,this);
						})
						.hover(
							function() {
								if(!g.colresize&&!$(this).hasClass('thMove')&&!g.colCopy) $(this).addClass('thOver');

								if($(this).attr('abbr')!=p.sortname&&!g.colCopy&&!g.colresize&&$(this).attr('abbr')) $('div',this).addClass('s'+p.sortorder);
								else if($(this).attr('abbr')==p.sortname&&!g.colCopy&&!g.colresize&&$(this).attr('abbr')) {
									var no='';
									if(p.sortorder=='asc') no='desc';
									else no='asc';
									$('div',this).removeClass('s'+p.sortorder).addClass('s'+no);
								}

								if(g.colCopy) {
									var n=$('th',g.hDiv).index(this);

									if(n==g.dcoln) return false;



									if(n<g.dcoln) $(this).append(g.cdropleft);
									else $(this).append(g.cdropright);

									g.dcolt=n;

								} else if(!g.colresize) {

									var nv=$('th:visible',g.hDiv).index(this);
									var onl=parseInt($('div:eq('+nv+')',g.cDrag).css('left'));
									var nw=parseInt($(g.nBtn).width())+parseInt($(g.nBtn).css('borderLeftWidth'));
									nl=onl-nw+Math.floor(p.cgwidth/2);

									$(g.nDiv).hide();$(g.nBtn).hide();

									$(g.nBtn).css({ 'left': nl,top: g.hDiv.offsetTop }).show();

									var ndw=parseInt($(g.nDiv).width());

									$(g.nDiv).css({ top: g.bDiv.offsetTop });

									if((nl+ndw)>$(g.gDiv).width())
										$(g.nDiv).css('left',onl-ndw+1);
									else
										$(g.nDiv).css('left',nl);

									if($(this).hasClass('sorted'))
										$(g.nBtn).addClass('srtd');
									else
										$(g.nBtn).removeClass('srtd');

								}

							},
							function() {
								$(this).removeClass('thOver');
								if($(this).attr('abbr')!=p.sortname) $('div',this).removeClass('s'+p.sortorder);
								else if($(this).attr('abbr')==p.sortname) {
									var no='';
									if(p.sortorder=='asc') no='desc';
									else no='asc';

									$('div',this).addClass('s'+p.sortorder).removeClass('s'+no);
								}
								if(g.colCopy) {
									$(g.cdropleft).remove();
									$(g.cdropright).remove();
									g.dcolt=null;
								}
							})
						; //wrap content
			 	}
			);

		//set bDiv
		g.bDiv.className='bDiv';
		$(t).before(g.bDiv);
		$(g.bDiv)
		.css({ height: (p.height=='auto')?'auto':p.height+"px" })
		.scroll(function(e) { g.scroll() })
		.append(t)
		;

		if(p.height=='auto') {
			$('table',g.bDiv).addClass('autoht');
		}


		//add td properties
		g.addCellProp();

		//add row properties
		g.addRowProp();

		//set cDrag

		var cdcol=$('thead tr:first th:first',g.hDiv).get(0);

		if(cdcol!=null) {
			g.cDrag.className='cDrag';
			g.cdpad=0;

			g.cdpad+=(isNaN(parseInt($('div',cdcol).css('borderLeftWidth')))?0:parseInt($('div',cdcol).css('borderLeftWidth')));
			g.cdpad+=(isNaN(parseInt($('div',cdcol).css('borderRightWidth')))?0:parseInt($('div',cdcol).css('borderRightWidth')));
			g.cdpad+=(isNaN(parseInt($('div',cdcol).css('paddingLeft')))?0:parseInt($('div',cdcol).css('paddingLeft')));
			g.cdpad+=(isNaN(parseInt($('div',cdcol).css('paddingRight')))?0:parseInt($('div',cdcol).css('paddingRight')));
			g.cdpad+=(isNaN(parseInt($(cdcol).css('borderLeftWidth')))?0:parseInt($(cdcol).css('borderLeftWidth')));
			g.cdpad+=(isNaN(parseInt($(cdcol).css('borderRightWidth')))?0:parseInt($(cdcol).css('borderRightWidth')));
			g.cdpad+=(isNaN(parseInt($(cdcol).css('paddingLeft')))?0:parseInt($(cdcol).css('paddingLeft')));
			g.cdpad+=(isNaN(parseInt($(cdcol).css('paddingRight')))?0:parseInt($(cdcol).css('paddingRight')));

			$(g.bDiv).before(g.cDrag);

			var cdheight=$(g.bDiv).height();
			var hdheight=$(g.hDiv).height();

			$(g.cDrag).css({ top: -hdheight+'px' });

			$('thead tr:first th',g.hDiv).each
			(
			 	function() {
			 		var cgDiv=document.createElement('div');
			 		$(g.cDrag).append(cgDiv);
			 		if(!p.cgwidth) p.cgwidth=$(cgDiv).width();
			 		$(cgDiv).css({ height: cdheight+hdheight })
						.mousedown(function(e) { g.dragStart('colresize',e,this); })
						;
			 		if($.browser.msie&&$.browser.version<7.0) {
			 			g.fixHeight($(g.gDiv).height());
			 			$(cgDiv).hover(
								function() {
									g.fixHeight();
									$(this).addClass('dragging')
								},
								function() { if(!g.colresize) $(this).removeClass('dragging') }
							);
			 		}
			 	}
			);

			//g.rePosDrag();

		}


		//add strip		
		if(p.striped)
			$('tbody tr:odd',g.bDiv).addClass('erow');


		if(p.resizable&&p.height!='auto') {
			g.vDiv.className='vGrip';
			$(g.vDiv)
		.mousedown(function(e) { g.dragStart('vresize',e) })
		.html('<span></span>');
			$(g.bDiv).after(g.vDiv);
		}

		if(p.resizable&&p.width!='auto'&&!p.nohresize) {
			g.rDiv.className='hGrip';
			$(g.rDiv)
		.mousedown(function(e) { g.dragStart('vresize',e,true); })
		.html('<span></span>')
		.css('height',$(g.gDiv).height())
		;
			if($.browser.msie&&$.browser.version<7.0) {
				$(g.rDiv).hover(function() { $(this).addClass('hgOver'); },function() { $(this).removeClass('hgOver'); });
			}
			$(g.gDiv).append(g.rDiv);
		}

		// add pager
		if(p.usepager) {
			g.pDiv.className='pDiv';
			g.pDiv.innerHTML='<div class="pDiv2"></div>';
			$(g.bDiv).after(g.pDiv);
			var html=' <div class="pGroup"> <div class="pFirst pButton"><span></span></div><div class="pPrev pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pcontrol">Page <input type="text" size="4" value="1" /> of <span> 1 </span></span></div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pNext pButton"><span></span></div><div class="pLast pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"> <div class="pReload pButton"><span></span></div> </div> <div class="btnseparator"></div> <div class="pGroup"><span class="pPageStat"></span></div>';
			$('div',g.pDiv).html(html);

			$('.pReload',g.pDiv).click(function() { g.populate() });
			$('.pFirst',g.pDiv).click(function() { g.changePage('first') });
			$('.pPrev',g.pDiv).click(function() { g.changePage('prev') });
			$('.pNext',g.pDiv).click(function() { g.changePage('next') });
			$('.pLast',g.pDiv).click(function() { g.changePage('last') });
			$('.pcontrol input',g.pDiv).keydown(function(e) { if(e.keyCode==13) g.changePage('input') });
			if($.browser.msie&&$.browser.version<7) $('.pButton',g.pDiv).hover(function() { $(this).addClass('pBtnOver'); },function() { $(this).removeClass('pBtnOver'); });

			if(p.useRp) {
				var opt="";
				for(var nx=0;nx<p.rpOptions.length;nx++) {
					if(p.rp==p.rpOptions[nx]) sel='selected="selected"';else sel='';
					opt+="<option value='"+p.rpOptions[nx]+"' "+sel+" >"+p.rpOptions[nx]+"&nbsp;&nbsp;</option>";
				};
				$('.pDiv2',g.pDiv).prepend("<div class='pGroup'><select name='rp'>"+opt+"</select></div> <div class='btnseparator'></div>");
				$('select',g.pDiv).change(
					function() {
						if(p.onRpChange)
							p.onRpChange(+this.value);
						else {
							p.newp=1;
							p.rp= +this.value;
							g.populate();
						}
					}
				);
			}

			//add search button
			if(p.searchitems) {
				$('.pDiv2',g.pDiv).prepend("<div class='pGroup'> <div class='pSearch pButton'><span></span></div> </div>  <div class='btnseparator'></div>");
				$('.pSearch',g.pDiv).click(function() { $(g.sDiv).slideToggle('fast',function() { $('.sDiv:visible input:first',g.gDiv).trigger('focus'); }); });
				//add search box
				g.sDiv.className='sDiv';

				sitems=p.searchitems;

				var sopt="";
				for(var s=0;s<sitems.length;s++) {
					if(p.qtype==''&&sitems[s].isdefault==true) {
						p.qtype=sitems[s].name;
						sel='selected="selected"';
					} else sel='';
					sopt+="<option value='"+sitems[s].name+"' "+sel+" >"+sitems[s].display+"&nbsp;&nbsp;</option>";
				}

				if(p.qtype=='') p.qtype=sitems[0].name;

				$(g.sDiv).append("<div class='sDiv2'>Quick Search <input type='text' size='30' name='q' class='qsbox' /> <select name='qtype'>"+sopt+"</select> <input type='button' value='Clear' /></div>");

				$('input[name=q],select[name=qtype]',g.sDiv).keydown(function(e) { if(e.keyCode==13) g.doSearch() });
				$('input[value=Clear]',g.sDiv).click(function() { $('input[name=q]',g.sDiv).val('');p.query='';g.doSearch(); });
				$(g.bDiv).after(g.sDiv);

			}

		}
		$(g.pDiv,g.sDiv).append("<div style='clear:both'></div>");

		// add title
		if(p.title) {
			g.mDiv.className='mDiv';
			g.mDiv.innerHTML='<div class="ftitle">'+p.title+'</div>';
			$(g.gDiv).prepend(g.mDiv);
			if(p.showTableToggleBtn) {
				$(g.mDiv).append('<div class="ptogtitle" title="Minimize/Maximize Table"><span></span></div>');
				$('div.ptogtitle',g.mDiv).click
					(
					 	function() {
					 		$(g.gDiv).toggleClass('hideBody');
					 		$(this).toggleClass('vsble');
					 	}
					);
			}
			//g.rePosDrag();
		}

		//setup cdrops
		g.cdropleft=document.createElement('span');
		g.cdropleft.className='cdropleft';
		g.cdropright=document.createElement('span');
		g.cdropright.className='cdropright';

		//add block
		g.block.className='gBlock';
		var gh=$(g.bDiv).height();
		var gtop=g.bDiv.offsetTop;
		$(g.block).css(
		{
			width: g.bDiv.style.width,
			height: gh,
			background: 'white',
			position: 'relative',
			marginBottom: (gh* -1),
			zIndex: 1,
			top: gtop,
			left: '0px'
		}
		);
		$(g.block).fadeTo(0,p.blockOpacity);

		// add column control
		if($('th',g.hDiv).length) {

			g.nDiv.className='nDiv';
			g.nDiv.innerHTML="<table cellpadding='0' cellspacing='0'><tbody></tbody></table>";
			$(g.nDiv).css(
			{
				marginBottom: (gh* -1),
				display: 'none',
				top: gtop
			}
			).noSelect()
			;

			var cn=0;


			$('th div',g.hDiv).each
			(
			 	function() {
			 		var kcol=$("th[axis='col"+cn+"']",g.hDiv)[0];
			 		var chk='checked="checked"';
			 		if(kcol.style.display=='none') chk='';

			 		$('tbody',g.nDiv).append('<tr><td class="ndcol1"><input type="checkbox" '+chk+' class="togCol" value="'+cn+'" /></td><td class="ndcol2">'+this.innerHTML+'</td></tr>');
			 		cn++;
			 	}
			);

			if($.browser.msie&&$.browser.version<7.0)
				$('tr',g.nDiv).hover
				(
				 	function() { $(this).addClass('ndcolover'); },
					function() { $(this).removeClass('ndcolover'); }
				);

			$('td.ndcol2',g.nDiv).click
			(
			 	function() {
			 		if($('input:checked',g.nDiv).length<=p.minColToggle&&$(this).prev().find('input')[0].checked) return false;
			 		return g.toggleCol($(this).prev().find('input').val());
			 	}
			);

			$('input.togCol',g.nDiv).click
			(
			 	function() {

			 		if($('input:checked',g.nDiv).length<p.minColToggle&&this.checked==false) return false;
			 		$(this).parent().next().trigger('click');
			 		//return false;
			 	}
			);


			$(g.gDiv).prepend(g.nDiv);

			$(g.nBtn).addClass('nBtn')
			.html('<div></div>')
			.attr('title','Hide/Show Columns')
			.click
			(
			 	function() {
			 		$(g.nDiv).toggle();return true;
			 	}
			);

			if(p.showToggleBtn) $(g.gDiv).prepend(g.nBtn);

		}

		// add date edit layer
		$(g.iDiv)
		.addClass('iDiv')
		.css({ display: 'none' })
		;
		$(g.bDiv).append(g.iDiv);

		// add flexigrid events
		$(g.bDiv)
		.hover(function() { $(g.nDiv).hide();$(g.nBtn).hide(); },function() { if(g.multisel) g.multisel=false; })
		;
		$(g.gDiv)
		.hover(function() { },function() { $(g.nDiv).hide();$(g.nBtn).hide(); })
		;

		//add document events
		$(document)
		.mousemove(function(e) { g.dragMove(e) })
		.mouseup(function(e) { g.dragEnd() })
		.hover(function() { },function() { g.dragEnd() })
		;

		//browser adjustments
		if($.browser.msie&&$.browser.version<7.0) {
			$('.hDiv,.bDiv,.mDiv,.pDiv,.vGrip,.tDiv, .sDiv',g.gDiv)
			.css({ width: '100%' });
			$(g.gDiv).addClass('ie6');
			if(p.width!='auto') $(g.gDiv).addClass('ie6fullwidthbug');
		}

		g.rePosDrag();
		g.fixHeight();

		//make grid functions accessible
		t.p=p;
		t.grid=g;

		// load data
		if(p.url&&p.autoload) {
			g.populate();
		}

		return t;

	};

	var docloaded=false;

	$(document).ready(function() { docloaded=true });

	$.fn.flexigrid=function(p) {

		return this.each(function() {
			if(!docloaded) {
				$(this).hide();
				var t=this;
				$(document).ready
					(
						function() {
							$.addFlex(t,p);
						}
					);
			} else {
				$.addFlex(this,p);
			}
		});

	}; //end flexigrid

	$.fn.flexReload=function(p) { // function to reload grid

		return this.each(function() {
			if(this.grid&&this.p.url) this.grid.populate();
		});

	}; //end flexReload

	$.fn.flexOptions=function(p) { //function to update general options

		return this.each(function() {
			if(this.grid) $.extend(this.p,p);
		});

	}; //end flexOptions

	$.fn.flexToggleCol=function(cid,visible) { // function to reload grid

		return this.each(function() {
			if(this.grid) this.grid.toggleCol(cid,visible);
		});

	}; //end flexToggleCol

	$.fn.flexAddData=function(data) { // function to add data to grid

		return this.each(function() {
			if(this.grid) this.grid.addData(data);
		});

	};

	$.fn.noSelect=function(p) { //no select plugin by me :-)

		if(p==null)
			prevent=true;
		else
			prevent=p;

		if(prevent) {

			return this.each(function() {
				if($.browser.msie||$.browser.safari) $(this).bind('selectstart',function() { return false; });
				else if($.browser.mozilla) {
					$(this).css('MozUserSelect','none');
					$('body').trigger('focus');
				}
				else if($.browser.opera) $(this).bind('mousedown',function() { return false; });
				else $(this).attr('unselectable','on');
			});

		} else {


			return this.each(function() {
				if($.browser.msie||$.browser.safari) $(this).unbind('selectstart');
				else if($.browser.mozilla) $(this).css('MozUserSelect','inherit');
				else if($.browser.opera) $(this).unbind('mousedown');
				else $(this).removeAttr('unselectable','on');
			});

		}

	}; //end noSelect

})(jQuery);